#include <inctypes.h>
#include <incctrls.h>

/*********************************************************************************
 * 
 * krl_device_init - 初始化设备管理结构体
 * 
 * DESCRIPTION
 * 
 */

void krl_device_init (void)
    {
    devtable_t_init (&osdevtable);
    return;
    }

/*********************************************************************************
 * 
 * devclasslst_t_init - 初始化设备类型挂载表
 * 
 * DESCRIPTION
 * 
 */

void devclasslst_t_init
    (
    devclasslst_t *      devclslstp,
    enum DEVICE_CLASSIFY type
    )
    {
    devclslstp->type  = type;      /* 设备类型 */
    devclslstp->count = 0;         /* 设备计数 */
    list_init (&devclslstp->list); 
    
    return;
    }

/*********************************************************************************
 * 
 * devtable_t_init - 初始化设备表
 * 
 * DESCRIPTION
 * 
 */

void devtable_t_init
    (
    devtable_t * devtblp
    )
    {
    uint_t i;

    hal_spinlock_init (&devtblp->lock);  /* 初始化自旋锁 */
    list_init (&devtblp->list);          /* 初始化链表 */
    list_init (&devtblp->devlist);       /* 初始化链表 */
    list_init (&devtblp->drvlist);       /* 初始化链表 */

    devtblp->devcount = 0;               /* 初始化设备计数器 */
    devtblp->drvcount = 0;               /* 初始化驱动计数器 */

    /* 初始化每个设备类型挂载链表 */

    for (i = 0; i < DEVICE_CLASSITY_MAX_NBR; i++)
        {
        devclasslst_t_init (&devtblp->classlist[i], i);
        }

    return;
    }

/*********************************************************************************
 * 
 * krl_driver_init - 初始化所有驱动程序 (调用所有驱动 entry)
 * 
 * DESCRIPTION
 * 
 */

void krl_driver_init (void)
    {
    uint_t i;

    /* 初始化所有设备类型挂载下的驱动 */

    for (i = 0; osdrventrytbl[i] != NULL; i++)
        {
        if (krl_driverentry_run (osdrventrytbl[i]) == ERROR)
            {
            krl_system_die ("init driver err\r\n");
            return;
            }
        }

    return;
    }

/*********************************************************************************
 * 
 * drv_dipcunc_default - 默认驱动分发程序
 * 
 * DESCRIPTION
 * 
 */

drvstus_t drv_dipcunc_default
    (
    device_t * devp, 
    void *     param
    )
    {
    return ERROR;
    }

/*********************************************************************************
 * 
 * krl_add_driver_to_system - 加载驱动程数据结构到系统中
 * 
 * DESCRIPTION
 * 
 */

drvstus_t krl_add_driver_to_system
    (
    driver_t * drvp
    )
    {
    cpuflg_t  cpuflg;

    devtable_t * devtable = &osdevtable;

    /* 自旋锁加锁 */

    spinlock_saveflg_cli (&devtable->lock, &cpuflg);

    /* 把 driver 指向的 driver_t 结构体挂载到 devtable 的 drvlist 链表中 */

    list_add (&drvp->list, &devtable->drvlist);

    /* 增加驱动计数 */

    devtable->drvcount++;

    /* 自旋锁解锁 */

    spinunlock_restflg_sti (&devtable->lock, &cpuflg);

    return OK;
    }

/*********************************************************************************
 * 
 * drv_set_driverid - 设置驱动程序ID
 * 
 * DESCRIPTION
 * 
 */

void drv_set_driverid
    (
    driver_t * drvp
    )
    {

    /* 每个驱动程序数据结构都有唯一内存空间地址, 可以作为 ID */

    drvp->id = (uint_t) drvp;

    return;
    }

/*********************************************************************************
 * 
 * driver_t_init - 初始化驱动程序结构体
 * 
 * DESCRIPTION
 * 
 */

void driver_t_init 
    (
    driver_t * driver
    )
    {
    uint_t i;

    hal_spinlock_init (&driver->lock);
    list_init (&driver->list);

    driver->status       = 0;
    driver->flag         = 0;
    krl_set_driverid (driver);    /* 设置驱动程序ID */
    driver->refcnt       = 0;
    krl_sem_init (&driver->sem);
    driver->safedsc      = NULL;
    driver->attribute    = NULL;
    driver->private_data = NULL;

    /* 初始化驱动程序功能派发函数  */

    for (i = 0; i < IOIF_OPCODE_MAX; i++)
        {
        driver->dipfunc[i] = drv_dipcunc_default;
        }

    list_init (&driver->alldevlist);
    driver->drventry  = NULL;
    driver->drvexit   = NULL;
    driver->user_data = NULL;
    driver->name      = NULL;

    return;
    }

/*********************************************************************************
 * 
 * drv_create_driverdsc - 创建驱动程序数据结构的实例变量
 * 
 * DESCRIPTION
 * 
 */

driver_t * drv_create_driverdsc (void)
    {

    /* 分配驱动程序结构的实例变量空间 */

    driver_t * driver = (driver_t *) krl_mem_new (sizeof (driver_t));

    if (driver == NULL)
        {
        return NULL;
        }

    /* 初始化驱动程序数据结构 */

    driver_t_init (driver);

    return driver;
    }

/*********************************************************************************
 * 
 * drv_delete_driverdsc - 删除驱动程序数据结构的实例变量
 * 
 * DESCRIPTION
 * 
 */

drvstus_t drv_delete_driverdsc 
    (
    driver_t * drvp
    )
    {
    if (krl_mem_delete ((addr_t) drvp, sizeof (driver_t)) == FALSE)
        {
        return ERROR;
        }

    return OK;
    }

/*********************************************************************************
 * 
 * krl_driverentry_run - 调用驱动入口函数并将驱动数据加进系统
 * 
 * DESCRIPTION
 * 
 */

drvstus_t krl_driverentry_run
    (
    drventry_t drventry
    )
    {
    
    /* 创建驱动程序数据结构的实例变量 */

    driver_t * driver = drv_create_driverdsc ();

    if (driver == NULL)
        {
        return NULL;
        }

    /* 调用驱动程序的入口函数 */

    if (drventry (driver, 0, NULL) == ERROR)
        {
        return ERROR;
        }

    /* 驱动程序入口函数正确返回, 加载驱动程序数据结构到系统 */

    if (krl_add_driver_to_system (driver) == ERROR)
        {
        return ERROR;
        }

    return OK;
    }

/*********************************************************************************
 * 
 * dev_devid_init - 初始化设备ID
 * 
 * DESCRIPTION
 * 
 */

void dev_devid_init
    (
    devid_t *            didp,
    enum DEVICE_CLASSIFY majtype,
    enum DEVICE_CLASSIFY subtype,
    uint_t               index
    )
    {
    didp->majtype = majtype;
    didp->subtype = subtype;
    didp->index   = index;

    return;
    }

/*********************************************************************************
 * 
 * device_t_init - 初始化设备数据结构
 * 
 * DESCRIPTION
 * 
 */

void device_t_init 
    (
    device_t * devp
    )
    {

    /* 初始化链表 */
    
    list_init (&devp->list);
    list_init (&devp->drvlist);
    list_init (&devp->tbllist);
    list_init (&devp->isrlist);
    list_init (&devp->rqlist);

    /* 初始化自旋锁 */

    hal_spinlock_init (&devp->lock);
    
    /* 初始化信号量 */

    krl_sem_init (&devp->sem);
    krl_sem_init (&devp->sem_waitdev);

    /* 初始化设备ID */

    dev_devid_init (&devp->id, 0, 0, 0);

    /* 其他成员初始化 */

    devp->count        = 0;
    devp->status       = 0;
    devp->flag         = 0;
    devp->isrnbr       = 0;
    devp->rqnbr        = 0;
    devp->driver       = NULL;
    devp->attribute    = NULL;
    devp->private_data = NULL;
    devp->user_data    = NULL;
    devp->name         = NULL;

    return;
    }

/*********************************************************************************
 * 
 * dev_create_devicedsc - 创建 device_t 并初始化
 * 
 * DESCRIPTION
 * 
 */

device_t * dev_create_devicedsc (void)
    {

    /* 分配设备数据结构实例变量的内存空间 */

    device_t * device = (device_t *) krl_mem_new (sizeof (device_t));

    if (device == NULL)
        {
        return NULL;
        }

    /* 执行设备数据结构初始化工作 */

    device_t_init (device);

    return device;
    }

/*********************************************************************************
 * 
 * dev_delete_devicedsc - 删除设备数据结构的实例变量
 * 
 * DESCRIPTION
 * 
 */

drvstus_t dev_delete_devicedsc 
    (
    device_t * devp
    )
    {
    if (krl_mem_delete ((addr_t) devp, sizeof (device_t)) == FALSE)
        {
        return ERROR;
        }

    return OK;
    }

/*********************************************************************************
 * 
 * compare - 比较设备ID
 * 
 * DESCRIPTION
 * 
 */

bool_t dev_compare_devid
    (
    devid_t * didp1,
    devid_t * didp2
    )
    {

    /* 比较 majtype, subtype, index */

    if ((didp1->majtype != didp2->majtype) ||
        (didp1->subtype != didp2->subtype) ||
        (didp1->index != didp2->index))
        {
        return FALSE;
        }

    return TRUE;
    }

/*********************************************************************************
 * 
 * dev_add_device_to_driver - 把设备数据结构加入到相应的驱动程序数据结构中
 * 
 * DESCRIPTION
 * 
 */

drvstus_t dev_add_device_to_driver
    (
    device_t * devp,
    driver_t * drvp
    )
    {
    list_t *   list;
    device_t * devtmp;

    /* 检查输入参数有效性 */

    if ((devp == NULL) || (drvp == NULL))
        {
        return ERROR;
        }

    /* 
     * 遍历 driver_t 结构体中的 alldevlist 链表上的所有 device_t 结构体,
     * 并与要加入的 device_t 结构体对比 (设备ID)
     */

    list_for_each (list, &drvp->alldevlist)
        {
        devtmp = list_entry (list, device_t, drvlist);

        if (dev_compare_devid (&devp->id, &devtmp->id) == TRUE)
            {
            return ERROR;   /* 设备ID已存在, 加入失败 */
            }
        }

    /* 
     * 未找到 设备ID, 将该 device_t 结构加入到 driver_t 的 alldevlist 链表上,
     * 同时将该 device_t 结构的 driver 指向 driver_t 结构.
     */

    list_add (&devp->drvlist, &drvp->alldevlist);
    devp->driver = drvp;

    return OK;
    }

/*********************************************************************************
 * 
 * krl_dev_register_device - 向内核注册设备
 * 
 * DESCRIPTION
 * 
 */

drvstus_t krl_dev_register_device
    (
    device_t * devp
    )
    {
    device_t *           devfind;
    drvstus_t            retstus;
    cpuflg_t             cpuflg;
    list_t *             list;
    devtable_t *         devtbl  = &osdevtable;
    enum DEVICE_CLASSIFY majtype = devp->id.majtype;

    /* 参数有效性检查 */

    if (devp == NULL)
        {
        return ERROR; 
        }

    /* 检查设备是否有对应的驱动程序 */

    if (devp->driver == NULL)
        {
        return ERROR;   /* 该设备未指定驱动 */
        }

    /* 检查设备主类型号有效性 */

    if (majtype >= DEVICE_CLASSITY_MAX_NBR)  
        {
        return ERROR;
        }

    spinlock_saveflg_cli (&devp->lock, &cpuflg);    /* 自旋锁 加锁 */

    /* 检查设备主类型和设备分类表元素类型是否一致 */

    if (majtype != devtbl->classlist[majtype].type)
        {
        retstus = ERROR;
        goto return_step;
        }

    /* 遍历这个设备类型挂载链表上的所有设备, 看是否有相同的设备ID */

    list_for_each (list, &devtbl->classlist[majtype].list)
        {
        devfind = list_entry (list, device_t, tbllist);

        if (dev_compare_devid (&devp->id, &devfind->id) == TRUE)
            {
            retstus = ERROR;    /* 设备ID已存在, 加入失败 */
            goto return_step;        
            }
        }

    /* 先把设备挂入该设备类型的挂载链表中 */

    list_add (&devp->tbllist, &devtbl->classlist[majtype].list);

    /* 增加该设备类型中的挂载计数 */

    devtbl->classlist[majtype].count++;

    /* 把设备挂入全局链表中 */

    list_add (&devp->list, &devtbl->devlist);

    /* 增加全局设备挂载计数 */

    devtbl->devcount++;    

    retstus = OK;    /* 操作成功 */

return_step:

    spinunlock_restflg_sti (&devp->lock, &cpuflg);    /* 自旋锁 解锁 */

    return retstus;
    }

/*********************************************************************************
 * 
 * krl_dev_register_isrhandle - 向内核注册中断回调函数
 * 
 * DESCRIPTION
 * 
 */

drvstus_t krl_dev_register_isrhandle
    (
    device_t *  devp,
    inthandle_t handle,
    uint_t      ifdidx
    )
    {
    cpuflg_t cpuflg;

    /* 安装设备回调函数并申请和返回 intisrdsc_t 结构体 */

    intisrdsc_t * intisrdsc = krl_add_isrhandle (devp, handle, ifdidx);

    if (intisrdsc == NULL)
        {
        return ERROR;
        }

    spinlock_saveflg_cli (&devp->lock, &cpuflg);    /* 自旋锁 加锁 */    

    /* 把 intisrdsc_t 结构体加入 device_t 的 isrlist 链表 */

    list_add (&intisrdsc->devlist, &devp->isrlist);

    devp->isrnbr++;   /* 该设备绑定的中断回调函数计数 +1 */

    spinunlock_restflg_sti (&devp->lock, &cpuflg);    /* 自旋锁 解锁 */    
    
    return OK;
    }

/*********************************************************************************
 * 
 * krl_dev_process_request - 处理设备请求
 * 
 * DESCRIPTION
 * 
 */

drvstus_t krl_dev_process_request
    (
    objnode_t * request
    )
    {
    drvstus_t retstus;

    /* 提取要访问的设备数据结构的指针 */

    device_t * device = (device_t * ) request->ptr;

    /* 检查 objnode_t 是否是访问设备的类型, 或者是否为 NULL */

    if ((request->type == OBJNODE_TYPE_DEV) ||
        (request->ptr == NULL))
        {
        return ERROR;
        }

    /* 检查 I/O 操作码的有效性 */

    if ((request->opcode < 0) || (request->opcode > IOIF_OPCODE_MAX))
        {
        return ERROR;
        }

    /* 调用这个设备的驱动程序 */

    retstus = dev_call_driver_dipfunc (device, request->opcode, 0, 0, NULL, request);

    return retstus;
    }


/*********************************************************************************
 * 
 * krl_dev_call_drvdipfunc - 调用驱动分发函数
 * 
 * DESCRIPTION
 * 
 */

drvstus_t krl_dev_call_drvdipfunc
    (
    device_t * devp,
    uint_t     opcode,
    uint_t     value1,
    uint_t     value2,
    void *     ptr1,
    void *     ptr2
    )
    {
    drvstus_t  retstus;
    driver_t * driver = NULL;

    /* 检查设备数据结构的指针和操作码有效性 */

    if ((devp == NULL) || (opcode >= IOIF_OPCODE_MAX))
        {
        return ERROR;
        }

    /* 获取这个设备相关的驱动程序数据结构的指针 */

    driver = devp->driver;

    if (driver == NULL)
        {
        return ERROR;
        }

    /* 调用驱动程序功能派发函数数组中的函数*/

    retstus = driver->dipfunc[opcode] (devp, ptr2);

    return retstus;
    }

/*********************************************************************************
 * 
 * krl_dev_add_request - 添加I/O包到设备请求链表
 * 
 * DESCRIPTION
 * 
 */

drvstus_t krl_dev_add_request
    (
    device_t *  devp,
    objnode_t * request
    )
    {
    cpuflg_t    cpuflg;
    objnode_t * objnode = (objnode_t * ) request;

    /* 自旋锁加锁 */

    spinlock_saveflg_cli (&devp->lock, &cpuflg);

    /* 把I/O包加到当前设备请求的链表中 */

    list_add_tail (&objnode->list, &devp->rqlist);

    /* 增加设备请求I/O包的计数 */

    devp->rqnbr++;

    /* 自旋锁解锁 */

    spinunlock_restflg_sti (&devp->lock, &cpuflg);

    return OK;
    }

/*********************************************************************************
 * 
 * krl_dev_wait_request - 等待设备请求
 * 
 * DESCRIPTION
 * 
 */

drvstus_t krl_dev_wait_request
    (
    device_t *  devp,
    objnode_t * request
    )
    {

    /* 检查设备指针和I/O包指针 */

    if ((devp == NULL) || (request == NULL))
        {
        return ERROR;
        }

    /* 获取 操作I/O包的 完成信号量 (不可用时将会阻塞) */

    krl_sem_take (&request->sem_complete);

    return OK;
    }

/*********************************************************************************
 * 
 * krl_dev_return_request - 遍历所有I/O包找到相应的I/O包并返回其指针
 * 
 * DESCRIPTION
 * 
 */

drvstus_t krl_dev_return_request
    (
    device_t *   devp,
    uint_t       opcode,
    objnode_t ** retreq
    )
    {
    drvstus_t   retstus;
    cpuflg_t    cpuflg;
    objnode_t * objnode;
    list_t *    list;

    /* 检查参数有效性 */

    if ((retreq == NULL) || (opcode >= IOIF_OPCODE_MAX))
        {
        return ERROR;
        }

    /* 自旋锁加锁 */

    spinlock_saveflg_cli (&devp->lock, &cpuflg);

    /* 遍历 device_t 解构的 rqlist 链表上所有的 I/O 包 */

    list_for_each (list, &devp->rqlist)
        {
        objnode = list_entry (list, objnode_t, list);

        /* 比较I/O操作码是否相同, 相同则通过retreq参数返回这个I/O包 */

        if (opcode == objnode->opcode)
            {
            *retreq = objnode;
            retstus = OK;
            goto return_step;
            }
        }

    /* 找到相同操作码的I/O包 */

    retstus = ERROR;
    *retreq = NULL;

return_step:

    /* 自旋锁解锁 */

    spinunlock_restflg_sti (&devp->lock, &cpuflg);

    return retstus;
    }

/*********************************************************************************
 * 
 * krl_dev_complete_request - 完成I/O包
 * 
 * DESCRIPTION
 * 
 */

drvstus_t krl_dev_complete_request
    (
    device_t *  devp,
    objnode_t * request
    )
    {
    cpuflg_t  cpuflg;
    
    /* 对参数有效性进行检查 */

    if ((devp == NULL) || (request == NULL))
        {
        return ERROR;
        }

    /* 如果 device_t 结构的 rqnbr < 1 说明没有相应的I/O包 (死机) */

    if (devp->rqnbr < 1)
        {
        krl_system_die ("dev_complete_request err\r\n");
        return ERROR;
        }

    /* 自旋锁加锁 */

    spinlock_saveflg_cli (&devp->lock, &cpuflg);
    
    /* 删除I/O包 */

    list_delete (&request->list);

    /* 设备I/O包计数 -1 */

    devp->rqnbr--;

    /* 自旋锁解锁 */

    spinunlock_restflg_sti (&devp->lock, &cpuflg);

    /* 操作信号量, 唤醒相关进程 */

    krl_sem_give (&request->sem_complete);
    
    return OK;
    }

/*********************************************************************************
 *
 * dev_inc_refcount - 增加设备引用计数变量值
 *
 * DESCRIPTION
 *
 */

drvstus_t dev_inc_refcount
    (
    device_t * devp
    )
    {
    cpuflg_t  cpuflg;
    drvstus_t retstus;

    /* 自旋锁加锁 */

    spinlock_saveflg_cli (&devp->lock, &cpuflg);

    /* 检查计数变量是否回绕 */

    if (devp->count >= (~0UL))
        {
        retstus = ERROR;
        goto return_step;
        }

    /* 计数变量 +1 */

    devp->count++;

    retstus = OK;

return_step:

    /* 自旋锁解锁 */

    spinunlock_restflg_sti (&devp->lock, &cpuflg);

    return retstus;
    }

/*********************************************************************************
 *
 * dev_dec_refcount - 减少设备引用计数变量值
 *
 * DESCRIPTION
 *
 */

drvstus_t dev_dec_refcount
    (
    device_t * devp
    )
    {
    cpuflg_t  cpuflg;
    drvstus_t retstus;

    /* 自旋锁加锁 */

    spinlock_saveflg_cli (&devp->lock, &cpuflg);

    /* 检查计数变量是否小于1  */

    if (devp->count < 1)
        {
        retstus = ERROR;
        goto return_step;
        }

    /* 计数变量 -1 */

    devp->count--;

    retstus = OK;

return_step:

    /* 自旋锁解锁 */

    spinunlock_restflg_sti (&devp->lock, &cpuflg);

    return retstus;
    }

/*********************************************************************************
 *
 * krl_return_reqstparam - 返回I/O请求中的参数
 *
 * DESCRIPTION
 *
 */

drvstus_t krl_return_reqstparam
    (
    const void *  request,
    buf_t *       r_buf,
    uint_t *      r_curops,
    uint_t *      r_len,
    uint_t *      r_ioctlcmd,
    uint_t *      r_bufcops,
    size_t *      r_bufsz
    )
    {

    /* 检查 request 参数有效性 */

    const objnode_t * objndp = (const objnode_t *) request;

    if (objndp == NULL)
        {
        return ERROR;
        }

    /* 获取 buf 成员值 */

    if (r_buf != NULL)
        {
        *r_buf = objndp->buf;
        }

    /* 获取 bufsz 成员值 */

    if (r_bufsz != NULL)
        {
        *r_bufsz = objndp->bufsz;
        }

    /* 获取 curops 成员值  */

    if (r_curops != NULL)
        {
        *r_curops = objndp->curops;
        }

    /* 获取 len 成员值 */

    if (r_len != NULL)
        {
        *r_len = objndp->len;
        }

    /* 获取 ioctlcmd 成员值 */

    if (r_ioctlcmd != NULL)
        {
        *r_ioctlcmd = objndp->ioctlcmd;
        }

    /* 返回 bufcurops 成员值 */

    if (r_bufcops != NULL)
        {
        *r_bufcops = objndp->bufcurops;
        }

    return OK;
    }

/*********************************************************************************
*
* krl_find_device - 查找相应的设备
*
* DESCRIPTION
*
*/

device_t * krl_find_device
    (
    void * devobj,
    uint_t flag
    )
    {
    device_t * fdevp;
    cpuflg_t   cpuflg;
    list_t *   lstp;

    /* 获取设备表指针 */

    devtable_t * devtblp = &osdevtable;

    /*
     * 检查参数有效性:
     * flag = DEV_ATTRFORM_IDN 表示 devobj 指向的是 devid_t 数据结构
     * flag = DEV_ATTRFORM_FLN 是 Linux 系统的 驱动模型纳入 文件系统的 形式
     */

    if ((devobj == NULL) || (flag != DEV_ATTRFORM_IDN))
        {
        return NULL;
        }

    /* 获取 devid_t 数据结构体 */

    devid_t * didp    = (devid_t *) devobj;
    uint_t    majtype = didp->majtype;

    /* 检查 主设备是否 有效 */

    if (majtype >= DEVICE_CLASSITY_MAX_NBR)
        {
        return NULL;
        }

    /* 自旋锁加锁 */

    spinlock_saveflg_cli (&devtblp->lock, &cpuflg);


    /* 判断 设备的主类型 是否等于 设备挂载数组中的设备主类型 */

    if (majtype != devtblp->classlist[majtype].type)
        {
        fdevp = NULL;
        goto return_step;
        }

    /* 遍历当前设备类型挂载链表上的所有设备 (比对设备ID) */

    list_for_each (lstp, &devtblp->classlist[majtype].list)
        {
        fdevp = list_entry (lstp, device_t, tbllist);

        /* 比对 device id */

        if (dev_compare_devid (didp, &fdevp->id) == TRUE)
            {
            fdevp = fdevp;
            goto return_step; /* 找到 */
            }
        }

    /* 没有找到相应的设备 */

    fdevp = NULL;

return_step:

    /* 自旋锁解锁 */

    spinunlock_restflg_sti (&devtblp->lock, &cpuflg);

    return fdevp;
    }

/* ============================== 服务相关 ============================== */

/*********************************************************************************
*
* krl_dev_calldriver - 调用驱动指定序号的分发函数
*
* DESCRIPTION
*
*/

drvstus_t krl_dev_calldriver
    (
    device_t * devp,
    uint_t     iocode,
    uint_t     val1,
    uint_t     val2,
    void *     ptr1,
    void *     ptr2
    )
    {
    driver_t * drvp;
    drvstus_t  retstus;

    /* 检验输入参数有效性 */

    if ((devp == NULL) ||
        (iocode < IOIF_OPCODE_MIN) || (iocode >= IOIF_OPCODE_MAX))
        {
        return ERROR;
        }

    /* 获得设备对应的驱动指针 */

    drvp = devp->driver;

    if (drvp == NULL)
        {
        return ERROR; /* 获得设备对应的驱动指针失败 */
        }

    /* 调用该驱动的分发函数 */

    retstus = drvp->dipfunc[iocode] (devp, ptr2);

    return retstus;
    }

/*********************************************************************************
*
* krl_dev_io - 设备 IO
*
* DESCRIPTION
*
*/

drvstus_t krl_dev_io
    (
    objnode_t * objndp
    )
    {
    device_t * devp;
    drvstus_t  retstus;
    
    /* 获得该 objnode 所属的 device_t */

    devp = (device_t *) (objndp->ptr);

    /* 检验子域有效性 */

    if (((objndp->type != OBJNODE_TYPE_DEV) && (objndp->type != OBJNODE_TYPE_FIL)) ||
        (objndp->ptr == NULL))
        {
        return ERROR;
        }

    /* 检验操作码范围有效性 */

    if ((objndp->opcode < IOIF_OPCODE_MIN) || (objndp->opcode >= IOIF_OPCODE_MAX))
        {
        return ERROR;
        }

    /* 按分发序号调用该设备对应的驱动 */

    retstus = krl_dev_calldriver (devp, objndp->opcode, 0, 0, NULL, objndp);

    return retstus;
    }
